package com.zyx.juc.cf;




import lombok.Getter;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Yaxi.Zhang
 * @since 2021/10/25 10:01
 * 案例说明：电商比价需求
 * 1 同一款产品，同时搜索出同款产品在各大电商的售价;
 * 2 同一款产品，同时搜索出本产品在某一个电商平台下，各个入驻门店的售价是多少
 *
 * 出来结果希望是同款产品的在不同地方的价格清单列表，返回一个 List<String>
 * 《mysql》 in jd price is 88.05
 * 《mysql》 in pdd price is 86.11
 * 《mysql》 in taobao price is 90.43
 *
 * 3 要求深刻理解
 *   3.1 函数式编程
 *   3.2 链式编程
 *   3.3 Stream流式计算
 */
public class CompletableFutureNetMallDemo {

    static List<NetMall> list = Arrays.asList(
            new NetMall("jd"),
            new NetMall("pdd"),
            new NetMall("taobao"),
            new NetMall("dangdangwang"),
            new NetMall("tmall")
    );

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        List<String> books1 = getPriceByStep(list, "mysql");
        for (String s : books1) {
            System.out.println(s);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("costTime =====>>>>> "+(endTime - startTime) + "ms");

        long s1 = System.currentTimeMillis();
        for (String book : getPriceByAsync(list, "mysql")) {
            System.out.println(book);
        }
        long e1 = System.currentTimeMillis();
        System.out.println("costTime =====>>>>> "+ (e1 - s1) + "ms");

    }

    public static List<String> getPriceByStep(List<NetMall> list, String productName) {
        return list.stream().map(f -> String.format("%s in %s price is %.2f", productName, f.getMallName(), f.calcPrice(productName))).collect(Collectors.toList());
    }

    public static List<String> getPriceByAsync(List<NetMall> list, String productName) {
        ExecutorService pool = Executors.newFixedThreadPool(1);
        return list.stream()
                .map(f -> {
                    System.out.println("cf thread =====>>>>> " + Thread.currentThread().getName());
                    return CompletableFuture.supplyAsync(() -> String.format("%s in %s price is %.2f", productName, f.getMallName(), f.calcPrice(productName)), pool);
                })
                .collect(Collectors.toList())
                .stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList());
    }


}

class NetMall
{
    @Getter
    private String mallName;

    public NetMall(String mallName)
    {
        this.mallName = mallName;
    }

    public double calcPrice(String productName)
    {
        // 检索需要1秒钟
        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
        return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);
    }
}

